/**
 * 
 */
package me.twoday.library.mine.common;

import java.io.Serializable;

import me.twoday.library.mine.common.base.BaseApplication;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.Log;

/**
 * 액티비티 전환에 사용되는 관리 클래스
 * 
 * @author 박우람
 * @since 2010.02.13
 */
@SuppressWarnings("rawtypes")
public class ActivityUtil
{
	private Context mContext;
	private Activity mActivity;
	private Intent mIntent;
	private Class mRemoveActivity;
	private int mRequestCode = -1;
	private boolean mRemoveTask;

	/**
	 * 기본 생성자
	 * 
	 * @param mParentActivity 부모 엑티비티
	 */
	public ActivityUtil(Context context)
	{
		this.mContext = context;
		this.mIntent = new Intent();
		this.mRemoveTask = false;
		
		// Context를 통해 새로운 엑티비티를 생성할 경우 다음의 플래그가 필요하다.
		mIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
	}
	
	/**
	 * 엑티비티를 활용하는 기본 생성자
	 * 
	 * @param mParentActivity 부모 엑티비티
	 */
	public ActivityUtil(Activity activity)
	{
		this.mContext = activity;
		this.mActivity = activity;
		this.mIntent = new Intent();
		this.mRemoveTask = false;
		
	}
	
	/**
	 * 새로 호출할 엑티비티를 설정한다.
	 * 
	 * @param cls 호출할 엑티비티 클래스
	 * @return ActivityUtil
	 */
	public ActivityUtil setTargetActivity(Class cls)
	{
		mIntent.setClass(mContext, cls);
		return this;
	}
	
	/**
	 * 새로운 태스크를 생성하도록 설정한다. 생성에 신중을 가하도록 한다.
	 * 
	 * @return ActivityUtil
	 */
	public ActivityUtil setNewTask()
	{
		mIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		mIntent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
		return this;
	}
	
	/**
	 * 엑티비티 스택에 기록을 남기지 않도록 설정한다.
	 * 
	 * @return ActivityUtil
	 */
	public ActivityUtil setNoHistory()
	{
		mIntent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
		return this;
	}
	
	/**
	 * '최근 실행된 엑티비티' 목록에서 제외한다.
	 * 
	 * @return ActivityUtil
	 */
	public ActivityUtil setNoRecents()
	{
		mIntent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
		return this;
	}
	
	/**
	 * 설정된 엑티비티까지 모든 엑티비티를 삭제한다.
	 * 
	 * @param cls 엑티비티 클래스
	 * @return ActivityUtil
	 */
	public ActivityUtil setRemoveToActivity(Class cls)
	{
		this.mRemoveActivity = cls;
		return this;
	}
	
	/**
	 * 새로생성되는 엑티비티에 넘길 변수 묶음
	 * 
	 * @param extras 추가 변수
	 * @return ActivityUtil
	 */
	public ActivityUtil setBundle(Bundle extras)
	{
		mIntent.putExtras(extras);
		return this;
	}
	
	/**
	 * startActivityForResult를 위한 요청 코드를 설정한다.
	 * 
	 * @param code 요청 코드
	 * @return ActivityUtil
	 */
	public ActivityUtil setRequestCode(int code)
	{
		this.mRequestCode = code;
		return this;
	}
	
	/**
	 * 테스크상의 모든 엑티비티를 삭제합니다.
	 * 
	 * @return ActivityUtil
	 */
	public ActivityUtil setRemoveTask()
	{
		this.mRemoveTask = true;
		return this;
	}
	
	/**
	 * 새로운 엑티비티에 넘길 변수를 추가합니다.
	 * 
	 * @param key 키
	 * @param value 값
	 * @return ActivityUtil
	 */
	public ActivityUtil putExtra(String key, String value)
	{
		mIntent.putExtra(key, value);
		return this;
	}
	
	/**
	 * 새로운 엑티비티에 넘길 변수를 추가합니다.
	 * 
	 * @param key 키
	 * @param value 값
	 * @return ActivityUtil
	 */
	public ActivityUtil putExtra(String key, int value)
	{
		mIntent.putExtra(key, value);
		return this;
	}
	
	/**
	 * 새로운 엑티비티에 넘길 변수를 추가합니다.
	 * 
	 * @param key 키
	 * @param value 값
	 * @return ActivityUtil
	 */
	public ActivityUtil putExtra(String key, long value)
	{
		mIntent.putExtra(key, value);
		return this;
	}
	
	/**
	 * 새로운 엑티비티에 넘길 변수를 추가합니다.
	 * 
	 * @param key 키
	 * @param value 값
	 * @return ActivityUtil
	 */
	public ActivityUtil putExtra(String key, double value)
	{
		mIntent.putExtra(key, value);
		return this;
	}
	
	/**
	 * 새로운 엑티비티에 넘길 변수를 추가합니다.
	 * 
	 * @param key 키
	 * @param value 값
	 * @return ActivityUtil
	 */
	public ActivityUtil putExtra(String key, boolean value)
	{
		mIntent.putExtra(key, value);
		return this;
	}
	
	/**
	 * 새로운 엑티비티에 넘길 변수를 추가합니다.
	 * 
	 * @param key 키
	 * @param value 값
	 * @return ActivityUtil
	 */
	public ActivityUtil putExtra(String key, Serializable value)
	{
		mIntent.putExtra(key, value);
		return this;
	}
	
	/**
	 * 새로운 엑티비티에 넘길 변수를 추가합니다.
	 * 
	 * @param key 키
	 * @param value 값
	 * @return ActivityUtil
	 */
	public ActivityUtil putExtra(String key, Parcelable value)
	{
		mIntent.putExtra(key, value);
		return this;
	}
	
	/**
	 * 새로운 엑티비티를 생성한다.
	 */
	public void show()
	{
		// 생성할 엑티비티가 정의되있지 않을경우 에러
		if(mIntent.getClass() == null)
		{
			MessageUtil.alert(mContext, "생성할 엑티비티가 정의되지 않았습니다");
		}
		else
		{
			// 전체 엑티비티를 삭제합니다.
			if(mRemoveTask)
			{
				BaseApplication.resetActivityStack();
				//mIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
			}
			// 삭제할 위치의 엑티비티 클래스가 정의되어있을 경우
			else if(mRemoveActivity != null)
			{
				Intent removeIntent = new Intent(mContext, mRemoveActivity);
				removeIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);
				mContext.startActivity(removeIntent);
			}
			
			// 예상치 못한 어플리케이션 종료시 복구를 위한 데이터 보관
			mIntent.putExtra("_APPLICATION_BACKUP_BUNDLE", BaseApplication.backupCurrentState());
			
			// 새로 생성하는 엑티비티로부터 값을 전달받을 목적의 경우
			if(mRequestCode > -1)
			{
				mActivity.startActivityForResult(mIntent, mRequestCode);
			}
			// 일반적인 엑티비티 시작
			else
			{
				mContext.startActivity(mIntent);
			}
		}
	}
}
